#include <opencv2/opencv.hpp>
#include <iostream>
// 定义一个结构体来表示直线，使用四个整数表示直线的两个端点
struct Line {
    int x1, y1, x2, y2;
    Line(int _x1, int _y1, int _x2, int _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {}
};

// 计算两条直线之间的距离（使用端点之间的最小距离）
double calculateLineDistance(const Line& line1, const Line& line2) {
    // 计算四个端点之间的距离，并返回最小值
    // ...（省略了具体的距离计算逻辑，可以使用点到点的距离公式）
    // 这里为了简化，我们假设使用了两条直线中点之间的距离作为近似
    cv::Point2f mid1((line1.x1 + line1.x2) / 2.0f, (line1.y1 + line1.y2) / 2.0f);
    cv::Point2f mid2((line2.x1 + line2.x2) / 2.0f, (line2.y1 + line2.y2) / 2.0f);
    return cv::norm(mid1 - mid2);
}
//std::vector<Line> FindlineTool(cv::Mat img, cv::Rect roi)
//{
//
//}
//int main(int argc, char** argv) {
//    // 读取图像
//    //cv::Mat src = cv::imread("111.bmp", cv::IMREAD_GRAYSCALE);
//    cv::Mat src = cv::imread("111.bmp");
//    cv::resize(src, src, cv::Size(640, 640), 0, 0, cv::INTER_LINEAR);
//    if (src.empty()) {
//        std::cerr << "Error: Could not open or find the image!\n";
//        return -1;
//    }
//    // 定义感兴趣区域（ROI）
//    cv::Rect roi(150, 400, 100, 151); // 假设ROI是一个矩形，起点(50,50)，宽200，高200
//    //cv::rectangle(src, cv::Point(150, 350), cv::Point(250, 450), cv::Scalar(255, 0, 0), 1);
//    
//    // 裁剪出ROI区域
//    cv::Mat roiImage = src(roi);
//  
//    // 边缘检测
//    cv::Mat edges;
//    cv::Canny(roiImage, edges, 50, 150, 3);
//    //使用膨胀操作把直线变得更明显点
//    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(-1, -1));
//    cv::dilate(edges, edges, kernel, cv::Point(-1, -1));
//    cv::imshow("Detected Lines in ROI", edges);
//    cv::waitKey(0);
//    // 霍夫变换检测直线
//    std::vector<cv::Vec2f> lines;
//    cv::HoughLines(edges, lines, 1, CV_PI / 180, 150);
//
//    // 存储合并后的直线
//    std::vector<Line> mergedLines;
//    // 遍历检测到的直线
//    for (size_t i = 0; i < lines.size(); i++) {
//        float rho = lines[i][0], theta = lines[i][1];
//        cv::Point pt1, pt2;
//        double a = cos(theta), b = sin(theta);
//        double x0 = a * rho, y0 = b * rho;
//        pt1.x = cvRound(x0 + 1000 * (-b)) + roi.x; // 加上ROI的x偏移
//        pt1.y = cvRound(y0 + 1000 * (a)) + roi.y;  // 加上ROI的y偏移
//        pt2.x = cvRound(x0 - 1000 * (-b)) + roi.x;
//        pt2.y = cvRound(y0 - 1000 * (a)) + roi.y;
//
//        Line currentLine(pt1.x, pt1.y, pt2.x, pt2.y);
//
//        bool merged = false;
//        // 尝试与已合并的直线进行合并
//        for (size_t j = 0; j < mergedLines.size(); j++) {
//            if (calculateLineDistance(mergedLines[j], currentLine) < 10) { // 假设阈值为10像素
//                // 合并逻辑（这里简单地取中点作为新直线的端点）
//                mergedLines[j].x1 = (mergedLines[j].x1 + currentLine.x1) / 2;
//                mergedLines[j].y1 = (mergedLines[j].y1 + currentLine.y1) / 2;
//                mergedLines[j].x2 = (mergedLines[j].x2 + currentLine.x2) / 2;
//                mergedLines[j].y2 = (mergedLines[j].y2 + currentLine.y2) / 2;
//                merged = true;
//                break;
//            }
//        }
//        // 如果没有合并，则添加到合并后的直线列表中
//        if (!merged) {
//            mergedLines.push_back(currentLine);
//        }
//    }
//    // 将合并后的直线绘制到原图上
//    for (const auto& line : mergedLines) {
//        cv::line(src, cv::Point(line.x1, line.y1), cv::Point(line.x2, line.y2), cv::Scalar(0, 0, 255), 1);
//    }
//    cv::rectangle(src, cv::Point(150, 400), cv::Point(250, 551), cv::Scalar(255, 0, 0), 1);
//    // 显示最终结果
//    cv::imshow("Detected Lines in ROI", src);
//    cv::waitKey(0);
//    return 0;
//}
int main(int argc, char** argv)
{
    //// 检查是否提供了图像路径作为命令行参数
    //if (argc != 2)
    //{
    //    std::cout << "Usage: " << argv[0] << " <Image_Path>" << std::endl;
    //    return -1;
    //}
     //读取图像
    //cv::Mat src = cv::imread("111.bmp", cv::IMREAD_GRAYSCALE);
    cv::Mat src = cv::imread("222.bmp");
    cv::resize(src, src, cv::Size(675, 640), 0, 0, cv::INTER_LINEAR);
    if (src.empty()) {
        std::cerr << "Error: Could not open or find the image!\n";
        return -1;
    }
    // 定义感兴趣区域（ROI）
    cv::Rect roi(250, 450, 150, 150); // 假设ROI是一个矩形，起点(50,50)，宽200，高200
    //cv::rectangle(src, cv::Point(150, 350), cv::Point(250, 450), cv::Scalar(255, 0, 0), 1);
    
    // 裁剪出ROI区域
    cv::Mat roiImage = src(roi);
   /* cv::imshow("ff", roiImage);
    cv::waitKey(0);*/

    // 转换为灰度图像
    cv::Mat gray;
    cv::cvtColor(roiImage, gray, cv::COLOR_BGR2GRAY);

    // 对图像进行高斯模糊处理，以减少噪声和细节
    cv::GaussianBlur(gray, gray, cv::Size(9, 9), 2, 2);
     cv::imshow("ff", gray);
    cv::waitKey(0);
    // 使用霍夫圆变换检测圆
    std::vector<cv::Vec3f> circles;
    //cv::HoughLines(edges, lines, 1, CV_PI / 180, 150);
     cv::HoughCircles(gray, circles, cv::HOUGH_GRADIENT, 1, gray.rows / 8,  // 最小检测间距
        50, 30,  // canny边缘检测与圆心检测阈值
        0, 0  // 最小和最大半径
    );
    //cv::HoughCircles(gray, circles, cv::HOUGH_GRADIENT, 1, gray.rows / 8,  // 最小检测间距
    //    200, 100,  // canny边缘检测与圆心检测阈值
    //    0, 0  // 最小和最大半径
    //);

    // 在图像上绘制检测到的圆
    for (size_t i = 0; i < circles.size(); i++)
    {
        cv::Vec3i c = circles[i];
        cv::Point center = cv::Point(c[0]+ roi.x, c[1]+ roi.y);
        // 绘制圆心
        cv::circle(src, center, 2, cv::Scalar(0, 255, 0), 3, cv::LINE_AA);
        // 绘制圆轮廓
        cv::circle(src, center, c[2], cv::Scalar(0, 0, 255), 3, cv::LINE_AA);
    }

    // 显示结果图像
    cv::imshow("Detected Circles", src);
    cv::waitKey(0);
    return 0;
}